﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DWLib
{
    /// <summary>
    /// Digital Watch class containing hours and minutes
    /// </summary>
    public partial class DigitalWatchA : UserControl, IDigitalWatch, IUpdatable
    {
        /// <summary>
        /// mode indicates whether hours or minutes should be altered
        /// </summary>
        /// <remarks>
        /// -1 = normal operation
        ///  0 = altering hours
        ///  1 = altering minutes
        /// </remarks>
        internal int mode;
        internal Time time;

        /// <summary>
        /// flash indicates whether the altered mode has to be drawn or not
        /// </summary>
        internal bool flash;

        public DigitalWatchA()
        {
            InitializeComponent();

            mode = -1;
            time = Time.getInstance();
            time.attach(this);
            flash = true;
        }

        /// <summary>
        /// Increments a time object. (either hours or minutes)
        /// </summary>
        /// <returns>true when exceeded the maximum(enforces a reset); false otherwise.</returns>
        public virtual bool increment()
        {
            bool ret;
            switch (mode)
            {
                case 1:
                    ret = time.minutes.increment();
                    display();
                    break;
                case 0:
                    ret = time.hours.increment();
                    display();
                    break;
                default:
                    ret = false;
                    display();
                    break;
            }

            return ret;
        }

        /// <summary>
        /// Decrements either minutes or hours
        /// </summary>
        /// <returns>true when exceeded the minimum(enforces a reset); false otherwise.</returns>
        public virtual bool decrement()
        {
            bool ret;

            switch (mode)
            {
                case 1:
                    ret = time.minutes.decrement();
                    display();
                    break;

                case 0:
                    ret = time.hours.decrement();
                    display();
                    break;

                default:
                    ret = false;
                    display();
                    break;
            }

            return ret;
        }

        /// <summary>
        /// changes between different modes (or resets the mode to default)
        /// </summary>
        public virtual void changeMode()
        {
            if (++mode > maxValue())
            {
                time.SetPaused(false);
                mode = -1;
            }
            else
            {
                time.SetPaused(true);
            }
        }

        /// <summary>
        /// Default mode of the clock
        /// </summary>
        /// <returns>1</returns>
        protected virtual int maxValue()
        {
            return 1;
        }

        /// <summary>
        /// Updates the time on the screen
        /// </summary>
        public void update()
        {
            if (InvokeRequired)
            {
                Invoke(new Action(update));
            }
            else
            {
                flash = !flash;
                display();
            }
        }

        /// <summary>
        /// Show the time on the form
        /// </summary>
        protected virtual void display()
        {
            //draw the hours depending on the mode
            labelHours.Text = (mode == 0 && flash) ? string.Empty : time.hours.ToString();
            //draw the minutes depending on the mode
            labelMinutes.Text = (mode == 1 && flash) ? string.Empty : time.minutes.ToString();
            //draw the seperator depending on the mode
            labelSeperator1.Text = (mode == -1 && flash) ? string.Empty : ":";
        }
    }
}
